#include <cstdlib>
#include <iostream>

#include <boost/program_options.hpp>

#include "common/config/config.h"
#include "common/log/log.h"

#include "database/migrator.h"
#include "stem.h"

std::string configFilename(const boost::program_options::variables_map& variables)
{
    if (variables.count("config"))
        return variables["config"].as<std::string>();

    return "config.ini";
}

void printHelp(const boost::program_options::options_description& options)
{
    std::cout
        << "Использование: datenaro [ПАРАМЕТР]…" << std::endl
        << "Предоставляет доступ к данным системы farado." << std::endl
        << std::endl;
    std::cout << options << std::endl;
}

int main(int argc, char* argv[])
{
    namespace po = boost::program_options;
    po::options_description options("Допустимые параметры");
    options.add_options()(
        "help,h",
        "вывести справочное сообщение с перечнем разрешенных параметров"
    )(
        "config,c",
        po::value<std::string>(),
        "задать альтернативный путь к файлу конфигурации"
    )(
        "upgrade,u",
        "включить режим обновления базы данных"
    );

    po::variables_map variables;
    try
    {
        po::store(po::parse_command_line(argc, argv, options), variables);
        po::notify(variables);
    }
    catch (const po::error& exception)
    {
        LOG_ERROR << exception.what();
        printHelp(options);
        return EXIT_FAILURE;
    }

    if (variables.count("help"))
    {
        printHelp(options);
        return EXIT_SUCCESS;
    }

    initConfig(configFilename(variables));
    initLog(
        "datenaro",
        CONFIG.fileLog.logPath,
        CONFIG.fileLog.rotationSize,
        CONFIG.fileLog.needSourceLocation,
        CONFIG.fileLog.needThreadId,
        CONFIG.fileLog.dateTimeFormat,
        CONFIG.fileLog.severityLevel,
        CONFIG.consoleLog.needSourceLocation,
        CONFIG.consoleLog.needThreadId,
        CONFIG.consoleLog.dateTimeFormat,
        CONFIG.consoleLog.severityLevel
    );

    // TODO: предусмотреть возможность выполнять downgrade
    // TODO: проверять текущую версию ЬД
    // TODO: предусмотреть возможность возвращать требуемую и текущую версию ЬД
    if (variables.count("upgrade"))
    {
        LOG_INFO << "Включен режим обновления базы данных";
        auto application = Database::Migrator();
        return application.run();
    }

    auto application = Stem();
    return application.run();
}
